package com.arpa.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.cache.PartyGroupCache;
import com.arpa.ntocc.common.common.cache.ShipmentCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.wms.cache.LocationCache;
import com.arpa.wms.cache.UnitCache;
import com.arpa.wms.cache.WarehouseCache;
import com.arpa.wms.common.util.OrderIdGeneratorUtil;
import com.arpa.wms.domain.dto.DifferenceDTO;
import com.arpa.wms.domain.dto.DifferenceItemDTO;
import com.arpa.wms.domain.entity.*;
import com.arpa.wms.domain.enums.*;
import com.arpa.wms.domain.vo.DifferenceItemVO;
import com.arpa.wms.domain.vo.DifferenceVO;
import com.arpa.wms.mapper.*;
import com.arpa.wms.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 盘点 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-09-30
 */
@Service
@Log4j2
public class DifferenceServiceImpl extends ServiceImpl<DifferenceMapper, Difference> implements IDifferenceService {

    @Autowired
    private ShipmentCache shipmentCache;
    @Autowired
    private IInboundService iInboundService;
    @Autowired
    private IInboundItemService iInboundItemService;
    @Autowired
    private IDifferenceItemService iDifferenceItemService;
    @Autowired
    private IOutboundItemService iOutboundItemService;
    @Autowired
    private IOutboundRegisterService iOutboundRegisterService;
    @Autowired
    private IOutboundService iOutboundService;
    @Autowired
    private WarehouseCache warehouseCache;
    @Autowired
    private UnitCache unitCache;
    @Autowired
    private LocationCache locationCache;
    @Autowired
    private PartyCache partyCache;

    @Resource
    private CountingMapper countingMapper;
    @Resource
    private CountingItemMapper countingItemMapper;

    @Resource
    private CountingRegisterMapper countingRegisterMapper;

    @Resource
    private LocationMapper locationMapper;

    @Autowired
    private IContainerService iContainerService;


    @Autowired
    @Lazy
    private IInventoryService iInventoryService;

    @Autowired
    private IInventoryRecordService iInventoryRecordService;
    @Autowired
    private PartyGroupCache partyGroupCache;

    /**
     * 保存
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean save(Difference entity) {
        if (StringUtils.isBlank(entity.getCode())) {
            entity.setCode(IdUtil.simpleUUID());
        }
        if (StringUtils.isBlank(entity.getCreatedBy())) {
            entity.setCreatedBy(UserUtil.getCode());
        }
        entity.setGroupCode(UserUtil.getBranchCode());
        return super.save(entity);
    }

    /**
     * 根据code更新实体
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateByCode(Difference entity) {
        if (StringUtils.isBlank(entity.getModifiedBy())) {
            entity.setModifiedBy(UserUtil.getCode());
        }
        return baseMapper.update(entity, new QueryWrapper<Difference>().lambda().eq(Difference::getCode, entity.getCode()).eq(Difference::getGroupCode,UserUtil.getBranchCode()));
    }

    /**
     * 查询列表
     *
     * @param differenceDTO
     * @return
     */
    @Override
    public List<DifferenceVO> queryList(DifferenceDTO differenceDTO) {
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StringUtils.isNotEmpty(differenceDTO.getSortField())) {
            differenceDTO.setSortField(CommonUtil.camel2Underline(differenceDTO.getSortField()));
        }
        return baseMapper.queryList(differenceDTO);
    }

    @Override
    public List<String> queryByGoodscode(List<String> list) {
        return baseMapper.queryByGoodsCode(list);
    }

    /**
     * 查询合计,包含总数
     *
     * @param differenceDTO
     * @return
     */
    @Override
    public DifferenceVO queryListSum(DifferenceDTO differenceDTO) {
        DifferenceVO differenceVO = baseMapper.queryListSum(differenceDTO);
        return differenceVO;
    }


    /**
     * 审核 盘点单
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int audit(final Difference entity) {
        Difference difference = getOne(new QueryWrapper<Difference>().lambda().eq(Difference::getCode, entity.getCode()).eq(Difference::getStatus,"0").eq(Difference::getGroupCode,UserUtil.getBranchCode()));
        if (ObjectUtil.isNull(difference)) {
            throw new ServiceException("差异单【 " + entity.getCode() + "】不存在或已审核!");
        }
        // 通过审核的差异单单生成 盘盈 或者盘亏 生成差异单
        if (CheckDifferenceStatusEnum.PASS.getValue().equals(entity.getStatus())) {
            addInOrOut(entity.getCode());
            // 更新盘点单状态
            countingMapper.update(null,new UpdateWrapper<Counting>().lambda().eq(Counting::getCode, difference.getCountingCode())
                    .eq(Counting::getGroupCode,UserUtil.getBranchCode())
                    .set(Counting::getStatus, CountingStatusEnum.AUDIT.getValue()));
            //更改盘点明细状态
            countingItemMapper.update(null,new UpdateWrapper<CountingItem>().lambda().eq(CountingItem::getCountingCode, difference.getCountingCode())
                    .set(CountingItem::getStatus, CountingStatusEnum.AUDIT.getValue()).eq(CountingItem::getGroupCode,UserUtil.getBranchCode()));
            //更改盘点登记状态
            countingRegisterMapper.update(null,new UpdateWrapper<CountingRegister>().lambda().eq(CountingRegister::getCountingCode, difference.getCountingCode())
                    .set(CountingRegister::getStatus, CountingStatusEnum.AUDIT.getValue()));
        }
        // 审核驳回的 盘点单状态变为待盘点 可以再次盘点登记
        if (CheckDifferenceStatusEnum.NO_PASS.getValue().equals(entity.getStatus())) {
            // 更新盘点单状态
            countingMapper.update(null,new UpdateWrapper<Counting>().lambda().eq(Counting::getCode, difference.getCountingCode()).eq(Counting::getGroupCode,UserUtil.getBranchCode())
                    .set(Counting::getStatus, CountingStatusEnum.WAIT_COUNT.getValue()));
            //更改盘点明细状态
            countingItemMapper.update(null,new UpdateWrapper<CountingItem>().lambda().eq(CountingItem::getCountingCode, difference.getCountingCode())
                    .set(CountingItem::getStatus, CountingStatusEnum.WAIT_COUNT.getValue()).set(CountingItem::getPdaOpStatus, CountingStatusEnum.NEW.getValue()).eq(CountingItem::getGroupCode,UserUtil.getBranchCode()));
            //更改盘点登记状态
            countingRegisterMapper.update(null,new UpdateWrapper<CountingRegister>().lambda().eq(CountingRegister::getCountingCode, difference.getCountingCode())
                    .set(CountingRegister::getStatus, CountingStatusEnum.WAIT_COUNT.getValue()).set(CountingRegister::getPdaOpStatus, CountingStatusEnum.NEW.getValue()).eq(CountingRegister::getGroupCode,UserUtil.getBranchCode()));
        }

        // TODO: 2020/10/26 差异单审核之后，盘点主单状态变为已审核？？
        String userCode = UserUtil.getCode();
        String userName = partyCache.translate(userCode);
        // 更新
        difference.setStatus(entity.getStatus());
        difference.setAuditCode(userCode);
        difference.setModifiedBy(userCode);
        difference.setModifiedName(userName);
        difference.setAuditName(userName);

        return baseMapper.update(difference, new QueryWrapper<Difference>().lambda().eq(Difference::getCode, entity.getCode()).eq(Difference::getGroupCode,UserUtil.getBranchCode()));
    }


    /**
     * 根据差异明细 盘盈或者盘亏 生成差异单
     *
     * @param differenceCode 差异单号
     */
    @Transactional(rollbackFor = {Exception.class})
    public void addInOrOut(String differenceCode) {
        String groupCode = UserUtil.getBranchCode();
        // 先把数量大于0的查出来，是盘盈，盘盈就是入库
        List<DifferenceItem> surplusItemList = iDifferenceItemService.list(new QueryWrapper<DifferenceItem>().lambda()
                .eq(DifferenceItem::getGroupCode,groupCode)
                .eq(DifferenceItem::getDifferenceCode, differenceCode)
                .gt(DifferenceItem::getDifferenceQuantity, BigDecimal.ZERO));

        // 把数量小于0的查出来，是盘亏，盘亏就是出库
        List<DifferenceItem> lossItemList = iDifferenceItemService.list(new QueryWrapper<DifferenceItem>().lambda()
                .eq(DifferenceItem::getGroupCode,groupCode)
                .eq(DifferenceItem::getDifferenceCode, differenceCode)
                .lt(DifferenceItem::getDifferenceQuantity, BigDecimal.ZERO));

        Difference diffEntity = this.getOne(new QueryWrapper<Difference>().lambda().eq(Difference::getCode, differenceCode).eq(Difference::getGroupCode,groupCode));
        String countingCode = diffEntity.getCountingCode();
        if (CollUtil.isNotEmpty(surplusItemList)) {
            Map<String, List<DifferenceItem>> differenceItemMap = surplusItemList.stream().collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getShipmentCode()).orElse("")));
            differenceItemMap.forEach((key, differenceItems) -> {

                // 生成入库单
                Inbound inbound = new Inbound();
                // 入库单号  RK+货主编码+yyyyMMdd+四位流水号
                inbound.setCode(OrderIdGeneratorUtil.generatorOrderId(OrderIdGeneratorUtil.OrderTypeEnum.RK, key,groupCode));
                inbound.setSourceCode(diffEntity.getCountingCode());
                inbound.setStatus(InboundStatusEnum.FINISH_IN.getValue());
                inbound.setType(ReceiveTypeEnum.COUNTING.getValue());
                inbound.setShipmentCode(key);
                inbound.setWarehouseCode(diffEntity.getWarehouseCode());
                inbound.setShipmentName(shipmentCache.translate(key));
                inbound.setGroupCode(groupCode);
                inbound.setCreatedBy(UserUtil.getCode());
                inbound.setCreatedName(partyCache.translate(UserUtil.getCode()));
                inbound.setGmtCreated(LocalDateTime.now());

                List<InboundItem> inboundItemList = differenceItems.stream().map(s -> {
                    InboundItem inboundItem = new InboundItem();
                    BeanUtils.copyProperties(s, inboundItem);
                    inboundItem.setCode(IdUtil.simpleUUID());
                    inboundItem.setInboundCode(inbound.getCode());
                    // 差异单由于是从库存中获取的，所以单位都是基本单位
                    inboundItem.setBasicUnit(s.getGoodsUnit());
                    inboundItem.setGoodsUnit(s.getGoodsUnit());
                    inboundItem.setBasicUnitName(s.getGoodsUnitName());
                    inboundItem.setGoodsUnitName(s.getGoodsUnitName());
                    inboundItem.setInboundQuantity(s.getDifferenceQuantity().abs());
                    inboundItem.setStatus(InboundStatusEnum.FINISH_IN.getValue());
                    inboundItem.setCreatedBy(UserUtil.getCode());
                    inboundItem.setCreatedName(partyCache.translate(UserUtil.getCode()));

                    return inboundItem;
                }).collect(Collectors.toList());

                //  计划数量， 取上架单总数量
                BigDecimal total = BigDecimal.ZERO;
                for (InboundItem e : inboundItemList) {
                    total = total.add(e.getInboundQuantity());
                }
                inbound.setPlanQuantity(total);
                //  入库数量，取上架单数量
                inbound.setInboundQuantity(total);
                iInboundService.save(inbound);
                iInboundItemService.saveBatch(inboundItemList);

            });

            /*surplusItemList.forEach(r->{
                //有库存直接更新库存数量
                //TODO 记录操作日志
                if(StrUtil.isNotBlank(r.getInventoryCode())){
                    iInventoryService.update(new UpdateWrapper<Inventory>().lambda()
                            .eq(Inventory::getGroupCode,groupCode)
                            .eq(Inventory::getCode,r.getInventoryCode())
                            .setSql("quantity=quantity+"+r.getDifferenceQuantity())
                    );
                }else{
                    //TODO 补登商品新增库存
                    generateAndSaveInventory(diffEntity,r,null);


                }
            });*/

        }

        if (CollUtil.isNotEmpty(lossItemList)) {
            Map<String, List<DifferenceItem>> differenceItemMap = lossItemList.stream().collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getShipmentCode()).orElse("")));
            differenceItemMap.forEach((key, differenceItems) -> {

                // 生成出库单
                Outbound outbound = new Outbound();
                outbound.setCode(OrderIdGeneratorUtil.generatorOrderId(OrderIdGeneratorUtil.OrderTypeEnum.CK, key,groupCode));
                //  来源单号
                outbound.setDeliveryCode(diffEntity.getCountingCode());
                outbound.setSourceCode(diffEntity.getCountingCode());
                outbound.setStatus(OutboundStatusEnum.FINISH_OUT.getValue());
                outbound.setType(DeliveryTypeEnum.OUT_LOSS.getValue());
                outbound.setWarehouseCode(diffEntity.getWarehouseCode());
                outbound.setShipmentCode(key);
                outbound.setShipmentName(shipmentCache.translate(key));
                outbound.setGroupCode(groupCode);
                outbound.setCreatedBy(UserUtil.getCode());
                outbound.setCreatedName(partyCache.translate(UserUtil.getCode()));
                outbound.setGmtCreated(LocalDateTime.now());
                //调用中台扣费(盘亏出库不用不扣费)
                //出库单明细
                List<OutboundItem> outboundItemList = differenceItems.stream().map(s -> {
                    OutboundItem outboundItem = new OutboundItem();
                    BeanUtils.copyProperties(s, outboundItem);
                    outboundItem.setCode(IdUtil.simpleUUID());
                    outboundItem.setOutboundCode(outbound.getCode());
                    outboundItem.setOutboundQuantity(s.getDifferenceQuantity().abs());
                    outboundItem.setPlanQuantity(s.getDifferenceQuantity().abs());
                    outboundItem.setRecheckQuantity(s.getDifferenceQuantity().abs());
                    outboundItem.setRecheckUnitQuantity(s.getDifferenceQuantity().abs());
                    outboundItem.setBasicUnit(s.getGoodsUnit());
                    outboundItem.setGoodsUnit(s.getGoodsUnit());
                    outboundItem.setBasicUnitName(s.getGoodsUnitName());
                    outboundItem.setGoodsUnitName(s.getGoodsUnitName());
                    outboundItem.setStatus(OutboundStatusEnum.NOT_OUT.getValue());
                    outboundItem.setCreatedBy(UserUtil.getCode());
                    outboundItem.setCreatedName(partyCache.translate(UserUtil.getCode()));

                    return outboundItem;
                }).collect(Collectors.toList());

                //出库确认表
                List<OutboundRegister> outboundRegisterList = outboundItemList.stream().map(s -> {
                    OutboundRegister outboundRegister = new OutboundRegister();
                    BeanUtils.copyProperties(s, outboundRegister);
                    outboundRegister.setCode(IdUtil.simpleUUID());
                    outboundRegister.setOutboundItemCode(s.getCode());
                    outboundRegister.setStatus(OutboundStatusEnum.NOT_OUT.getValue());
                    outboundRegister.setCreatedBy(UserUtil.getCode());
                    outboundRegister.setCreatedName(partyCache.translate(UserUtil.getCode()));
                    return outboundRegister;
                }).collect(Collectors.toList());


                //  计划数量， 取上架单总数量
                BigDecimal total = BigDecimal.ZERO;
                for (OutboundItem e : outboundItemList) {
                    total = total.add(e.getOutboundQuantity());

                }
                outbound.setPlanQuantity(total);
                outbound.setRecheckQuantity(total);
                outbound.setOutQuantity(total);
                iOutboundService.save(outbound);
                iOutboundItemService.saveBatch(outboundItemList);
                iOutboundRegisterService.saveBatch(outboundRegisterList);

            });

            //TODO 更新库存
          /*  lossItemList.forEach(r->{
                //有库存直接更新库存数量
                //TODO 记录操作日志
                if(StrUtil.isNotBlank(r.getInventoryCode())){
                    iInventoryService.update(new UpdateWrapper<Inventory>().lambda()
                            .eq(Inventory::getCode,r.getInventoryCode())
                            .setSql("quantity=quantity-"+r.getDifferenceQuantity().abs())
                    );

                    //判断库存是否需要释放托盘
                    InventoryVO inventoryVO = iInventoryService.getOneByCode(r.getInventoryCode());
                    if(StrUtil.isNotBlank(inventoryVO.getContainerBarCode())){
                        List<String> containerBarCodes = new ArrayList<>();
                        containerBarCodes.add(inventoryVO.getContainerBarCode());
                        iContainerService.batchReleaseContainerForEmptyInventory(containerBarCodes,groupCode);
                    }
                }
            });*/
        }
        //根据盘点数量更新库存
        List<CountingRegister> countingRegisters = countingRegisterMapper.selectList(new LambdaQueryWrapper<CountingRegister>()
                .eq(CountingRegister::getCountingCode, countingCode)
                .eq(CountingRegister::getGroupCode, groupCode));

        countingRegisters.forEach(r->{
            if(StrUtil.isNotBlank(r.getInventoryCode())){
                iInventoryService.update(new UpdateWrapper<Inventory>().lambda()
                        .eq(Inventory::getCode,r.getInventoryCode())
                        .set(Inventory::getQuantity,r.getCountingQuantity())
                );
                // 记录库存变动日志
                iInventoryRecordService.insertRecord(r.getInventoryCode(), r.getCountingCode(), r.getCountingQuantity(), InventoryRecordTypeEnum.COUNTING.getValue());
            } else {
                //补登商品新增库存
                generateAndSaveInventory(diffEntity,null,r);
            }
        });
        //如果是动盘需要清零库位动碰次数
        Counting counting=countingMapper.selectOne(new QueryWrapper<Counting>().lambda().eq(Counting::getCode,diffEntity.getCountingCode()).eq(Counting::getGroupCode,groupCode));
        if(ObjectUtil.isNotNull(counting)){
           List<Object> locations = countingItemMapper.selectObjs(new QueryWrapper<CountingItem>().lambda().eq(CountingItem::getGroupCode,groupCode).select(CountingItem::getLocation).eq(CountingItem::getCountingCode,counting.getCode()));
            if(IterUtil.isNotEmpty(locations)){
                locationMapper.update(null,new UpdateWrapper<Location>().lambda().in(Location::getCode,locations).set(Location::getActionNum,BigDecimal.ZERO).eq(Location::getGroupCode,groupCode));
                locations.forEach(r->locationCache.flushCache(r.toString()));
            }
        }

    }

    /**
     * 生成库存
     * @param difference
     * @param differenceItem
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public Result generateAndSaveInventory(Difference difference ,DifferenceItem differenceItem,CountingRegister countingRegister) {
        try {

            // 根据上架单、上架明细、上架确认生成库存
            Inventory  inventory = generateInventory(difference,differenceItem,countingRegister);
            // 查询是否有相同的库存
            Inventory sameInventory = iInventoryService.hasSameInventory(inventory.getLot(), inventory.getGoodsCode(), inventory.getLocation(),
                    inventory.getShipmentCode(), inventory.getGoodsStatus(), inventory.getIsLock(), inventory.getContainerBarCode(),inventory.getGmtStock());

            if(sameInventory != null){
                // 存在相同库存则只需调整库存
                iInventoryService.adjustQuantity(sameInventory.getCode(), inventory.getQuantity());
            }else {
                // 不存在相同库存则需要插入一条新库存信息
                iInventoryService.save(inventory);
                sameInventory = inventory;
            }

            // 记录库存变动日志
            iInventoryRecordService.insertRecord(sameInventory, difference.getCode(), inventory.getQuantity(), InventoryRecordTypeEnum.INBOUND.getValue());
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error(e.getMessage());
        }

        return Result.ok();
    }



    /**
     * 根据上架单、上架明细、上架确认生成库存明细
     * @param difference 差异单
     * @param differenceItem 差异单明细
     * @return
     */
    public Inventory generateInventory(Difference difference,DifferenceItem differenceItem,CountingRegister countingRegister){
        Inventory inventory = new Inventory();
        if (null != differenceItem) {
            BeanUtil.copyProperties(differenceItem,inventory,false);
            inventory.setUnitName(differenceItem.getGoodsUnitName());
            inventory.setQuantity(differenceItem.getDifferenceQuantity());
            inventory.setIsLock(differenceItem.getIsLock());
            // 如果不是托盘，则库存上不会记录容器号
            if(StrUtil.isBlank(differenceItem.getContainerBarCode())){
                inventory.setContainerBarCode(StrUtil.EMPTY);
            }
        }
        if (null != countingRegister) {
            BeanUtil.copyProperties(countingRegister,inventory,false);
            inventory.setUnitName(countingRegister.getGoodsUnitName());
            inventory.setQuantity(countingRegister.getCountingQuantity());
            inventory.setIsLock(countingRegister.getIsLock());
            // 如果不是托盘，则库存上不会记录容器号
            if(StrUtil.isBlank(countingRegister.getContainerBarCode())){
                inventory.setContainerBarCode(StrUtil.EMPTY);
            }
        }

        inventory.setCode(IdUtil.simpleUUID());
        inventory.setWarehouseCode(difference.getWarehouseCode());
        inventory.setDeleted(0);


        return inventory;
    }



    @Override
    public DifferenceVO getOneByCode(String code) {
        Difference difference = getOne(new QueryWrapper<Difference>().lambda().eq(Difference::getCode, code).eq(Difference::getGroupCode,UserUtil.getBranchCode()));
        if (null == difference) {
            log.error("差异单【{}】找不到",code);
            throw new ServiceException("差异单: " + code + "不存在!");
        }
        Counting counting = countingMapper.selectOne(new QueryWrapper<Counting>().lambda().eq(Counting::getCode, difference.getCountingCode()).eq(Counting::getGroupCode, UserUtil.getBranchCode()));


        DifferenceVO differenceVO = new DifferenceVO();
        BeanUtils.copyProperties(difference, differenceVO);


        DifferenceItemDTO differenceItemDTO = new DifferenceItemDTO();
        differenceItemDTO.setDifferenceCode(code);
        differenceItemDTO.setPageSize(Integer.MAX_VALUE);
        //获取盘点单明细信息
        List<DifferenceItemVO> differenceItemVOList = iDifferenceItemService.queryList(differenceItemDTO);
        differenceItemVOList.forEach(e -> {
            e.setGoodsUnitName(unitCache.translate(e.getGoodsUnit()));
            e.setLocationName(locationCache.translate(e.getLocation()));
        });

        differenceVO.setWarehouseName(warehouseCache.translate(differenceVO.getWarehouseCode()));
        differenceVO.setCountingTypeName(CountingTypeEnum.translate(counting.getType()));
        differenceVO.setGroupName(partyGroupCache.translate(differenceVO.getGroupCode()));

        differenceVO.setDifferenceItemList(differenceItemVOList);
        return differenceVO;
    }

}
